using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public abstract class PoolRulesBase : MonoBehaviour
{
	public static Delegate1Args<int> onNewTurn;

	public static Delegate0Args onFireBall;

	public static Delegate1Args<IPlayer> onGameOver;

	public static Delegate0Args onCueballPotted;

	protected GlobalState m_State = GlobalState.NONE;

	protected GlobalState m_PrevState;

	protected int m_Turn;

	protected bool m_WhiteBallPotted;

	protected bool m_WhiteHitBall;

	protected float m_Time;

	protected bool m_TimeOut;

	protected Dictionary<int, PoolBall> m_PottedBallList = new Dictionary<int, PoolBall>();

	protected List<PoolBall> m_PottedBallListThisRound = new List<PoolBall>();

	protected HashSet<int> m_HittedRailBallsThisRound = new HashSet<int>();

	protected bool m_HandleWhiteball = true;

	public GlobalState State
	{
		get
		{
			return m_State;
		}
		set
		{
			m_PrevState = m_State;
			m_State = value;
			BaseUIController.cueOperateArea.ChangeOperationType(value);
		}
	}

	public bool firstRound => m_Turn == 1;

	public Dictionary<int, PoolBall> PottedBallList => m_PottedBallList;

	public List<PoolBall> PottedBallListThisRound => m_PottedBallListThisRound;

	public bool HandleWhiteBall => m_HandleWhiteball;

	public void ReversePrevState()
	{
		m_State = m_PrevState;
	}

	protected virtual void Start()
	{
		Pools.ResetAllBalls(pottedOnly: false, black8Origin: true);
		TurnBegin();
	}

	protected virtual void Update()
	{
		if (State == GlobalState.ROLLING && CheckIsBallsDoneRolling(Pools.BallsArray) && CheckIsBallsDoneRolling(Pools.CustomBallsArray))
		{
			State = GlobalState.NONE;
			StartCoroutine(CheckResultAndChangeTurn(0.1f));
		}
		CustomUpdate();
	}

	protected bool CheckIsBallsDoneRolling(PoolBall[] balls)
	{
		int i = 0;
		for (int num = balls.Length; i < num; i++)
		{
			if ((bool)balls[i] && balls[i].BallState != PoolBall.State.HIDE && !balls[i].IsDoneRolling())
			{
				return false;
			}
		}
		return true;
	}

	public virtual void PotBall(PoolBall ball, PocketIndexes pocket)
	{
		ball.Potted(pocket);
		ball.CloseDrag();
		if (ball.ballType == BallType.WHITE)
		{
			m_WhiteBallPotted = true;
			if (onCueballPotted != null)
			{
				onCueballPotted();
			}
		}
		else if (ball.ballType != BallType.JIANGYOU && ball.ballType != BallType.DEMON)
		{
			m_PottedBallListThisRound.Add(ball);
		}
	}

	public virtual void OnBallFired()
	{
		State = GlobalState.ROLLING;
		if (onFireBall != null)
		{
			onFireBall();
		}
	}

	protected virtual void TurnBegin()
	{
		ConstantData.angularDrag = GameConfig.ANGULAR_VELOCITY_DRAG;
		m_Turn++;
		State = GlobalState.IDLE;
		BaseUIController.itemToolbar.EnableAllItem();
		if (m_WhiteBallPotted)
		{
			Pools.CueBall.Reset();
		}
		if (m_WhiteHitBall)
		{
			GameStatistics.MarkCueballHitNoBall(1);
		}
		m_WhiteHitBall = false;
		m_WhiteBallPotted = false;
		m_TimeOut = false;
		if (onNewTurn != null)
		{
			onNewTurn(m_Turn);
		}
	}

	protected virtual IEnumerator CheckResultAndChangeTurn(float time)
	{
		yield return new WaitForSeconds(time);
		int i = 0;
		for (int count = m_PottedBallListThisRound.Count; i < count; i++)
		{
			PoolBall poolBall = m_PottedBallListThisRound[i];
			m_PottedBallList.Add(poolBall.GetBallID(), poolBall);
		}
		m_PottedBallListThisRound.Clear();
		TurnBegin();
	}

	public virtual void WhiteBallHitBall(PoolBall ball)
	{
		if (!m_WhiteHitBall)
		{
			m_WhiteHitBall = true;
		}
	}

	public virtual void BallHitRail(PoolBall poolBall)
	{
		m_HittedRailBallsThisRound.Add(poolBall.GetBallID());
	}

	public virtual void Continue()
	{
	}

	public abstract void CueBallHitRail();

	public abstract void SetPlayers(params IPlayer[] players);

	protected abstract void CustomUpdate();

	protected abstract void CallPocket();

	protected abstract bool HandleFouls();

	public abstract bool CheckGameOver();
}
